/* *
 * @program: VideoDirector
 *
 * @description: ${description}
 *
 * @author: 909845
 *
 * @create: 2018-12-25 10:19
***/


#include <jsoncpp/value.h>
#include <Http/HttpReqMessage.h>
#include "LsgClient.h"
#include "../../Public/Typedef.h"

#define TAG "SID[" << m_url.strID << "]- "

CLsgClient::CLsgClient(const shared_ptr<CEventEngine> &spEngine, const weak_ptr<ILsgCallback> &wpCb):
        m_spEngine(spEngine),
        m_wpCallback(wpCb)
{
    DEBUG_LOG(TAG << "Create CLsgClient.");
}

CLsgClient::~CLsgClient()
{
    DEBUG_LOG(TAG << "Destory ~CLsgClient.");
}

Bool CLsgClient::Connect(const string &strUrl)
{
    Bool bSuccess = False;

    do
    {
        DEBUG_LOG(TAG << "LsgClient Connect to url = " << strUrl);
        if (!CUrlDefine::ParseUrl(strUrl, m_url))
        {
            ERROR_LOG(TAG << "ParseUrl failed, url = " << strUrl);
            break;
        }
        m_strSendMsg = GenHttpRequest(m_url);
        m_spHttpClient = shared_ptr<CHttpClient>(new CHttpClient(m_spEngine.get()));
        if (!m_spHttpClient->Request(m_url.strHost.c_str(), shared_from_this(), 3000))
        {
            ERROR_LOG(TAG << "Connect failed.  host = " << m_url.strHost);
            break;
        }
        bSuccess = True;

    } while (0);

    return bSuccess;
}

Bool CLsgClient::OnHttpClientSend(string &str)
{
    if (m_strSendMsg.empty())
    {
        return False;
    }
    str = m_strSendMsg;
    m_strSendMsg.clear();
    DEBUG_LOG(TAG << "OnHttpClientSend msg:\n" << str);
    return True;
}

void CLsgClient::OnHttpClientRecv(LPCSTR lpszBuffer, Int32 nLen)
{
    string strResp;
    strResp.append(lpszBuffer, nLen);
    DEBUG_LOG(TAG << "OnHttpClientRecv msg:\n" << strResp);
    string lsuUrl = GetLsuUrl(strResp);
    shared_ptr<ILsgCallback> spCb = m_wpCallback.lock();
    if (!lsuUrl.empty())
    {
        if (spCb)
        {
            spCb->OnLsgSuccess(lsuUrl);
        }
    }
    else
    {
        if (spCb)
        {
            spCb->OnLsgError(-1);
        }
    }
}

void CLsgClient::OnHttpClientClosed(Int32 nError)
{
    m_spHttpClient = nullptr;
    if (nError != 0)
    {
        WARN_LOG(TAG << "CLsgClient OnHttpClientClosed  nError = " << nError);
        shared_ptr<ILsgCallback> spCb = m_wpCallback.lock();
        if (spCb)
        {
            spCb->OnLsgError(-1);
        }
    }
}

string CLsgClient::GenHttpRequest(const CUrlDefine &urlDefine)
{
    Json::Value root;
    root[CConstVal::STR_STREAM_ID] = urlDefine.strID;
    root[CConstVal::STR_RECORD] = (urlDefine.strQuery.find("record=1")!=string::npos) ? "1" : "0";
    const string strJsonBody = root.toStyledString();

    CHttpReqMessage reqMessage;
    reqMessage.SetRequestLine("POST", urlDefine.strPath);
    reqMessage.SetHeaderField("User-Agent", "LivePublisher");
    reqMessage.SetHeaderField("Content-Type", "application/json");
    reqMessage.SetHeaderField("Connection", "close");
    reqMessage.SetHeaderField("content-Length", STR::NumberToString(strJsonBody.length()));
    reqMessage.SetHeaderField("X-REMUX-Session:", urlDefine.strID);
    reqMessage.SetBody(strJsonBody, "application/json");

    return reqMessage.GetPacket();
}

string CLsgClient::GetLsuUrl(const string &strResq) const
{
    string strLsuUrl = "";
    static const string STR_RESP_OK = CConstVal::STR_HTTP_OK;
    static const string STR_ADDR = "\"address\":\"";

    do{
        string::size_type nPos = 0;
        if (string::npos == strResq.find(STR_RESP_OK))
        {
            break;
        }
        if (string::npos == (nPos = strResq.find(STR_ADDR)))
        {
            break;
        }
        const string strValue = strResq.substr(nPos + STR_ADDR.size());
        if (string::npos == (nPos = strValue.find("\"")))
        {
            break;
        }
        strLsuUrl = strValue.substr(0, nPos);

    }while (0);

    return strLsuUrl;
}
